//! gRPC服务器启动模块
//! 
//! 提供便捷的方法启动和配置gRPC服务器

use std::net::SocketAddr;
use std::sync::Arc;
use tokio::signal;
use tonic::transport::Server;
use tracing::{info, error, warn};
use anyhow::Result;

use crate::sandbox_manager::SandboxManager;
use crate::grpc::{SandboxManagerServer, proto::sandbox_manager_service_server::SandboxManagerServiceServer};

/// gRPC服务器运行器
pub struct GrpcServerRunner {
    sandbox_manager: Arc<SandboxManager>,
    addr: SocketAddr,
}

impl GrpcServerRunner {
    /// 创建新的gRPC服务器运行器
    pub fn new(sandbox_manager: Arc<SandboxManager>, addr: SocketAddr) -> Self {
        Self {
            sandbox_manager,
            addr,
        }
    }

    /// 启动gRPC服务器
    pub async fn run(self) -> Result<()> {
        info!("正在启动gRPC服务器: {}", self.addr);

        let sandbox_service = SandboxManagerServer::new(self.sandbox_manager.clone());
        let service = SandboxManagerServiceServer::new(sandbox_service);

        let server = Server::builder()
            .add_service(service)
            .serve_with_shutdown(self.addr, shutdown_signal());

        info!("gRPC服务器成功启动，监听地址: {}", self.addr);
        
        match server.await {
            Ok(()) => {
                info!("gRPC服务器正常关闭");
                Ok(())
            }
            Err(e) => {
                error!("gRPC服务器运行出错: {}", e);
                Err(e.into())
            }
        }
    }

    /// 启动带有健康检查的gRPC服务器
    pub async fn run_with_health_check(self) -> Result<()> {
        info!("正在启动带健康检查的gRPC服务器: {}", self.addr);

        let sandbox_service = SandboxManagerServer::new(self.sandbox_manager.clone());
        let service = SandboxManagerServiceServer::new(sandbox_service);

        let server = Server::builder()
            .add_service(service)
            // 可以在这里添加健康检查服务
            // .add_service(health_service)
            .serve_with_shutdown(self.addr, shutdown_signal());

        info!("带健康检查的gRPC服务器成功启动，监听地址: {}", self.addr);
        
        // 启动后台健康检查任务
        let health_manager = self.sandbox_manager.clone();
        tokio::spawn(async move {
            let mut interval = tokio::time::interval(std::time::Duration::from_secs(30));
            loop {
                interval.tick().await;
                let health = health_manager.perform_health_check().await;
                if health.is_err() {
                    warn!("系统健康检查失败: {:?}", health);
                }
            }
        });
        
        match server.await {
            Ok(()) => {
                info!("带健康检查的gRPC服务器正常关闭");
                Ok(())
            }
            Err(e) => {
                error!("gRPC服务器运行出错: {}", e);
                Err(e.into())
            }
        }
    }
}

/// 等待关闭信号
async fn shutdown_signal() {
    let ctrl_c = async {
        signal::ctrl_c()
            .await
            .expect("failed to install Ctrl+C handler");
    };

    #[cfg(unix)]
    let terminate = async {
        signal::unix::signal(signal::unix::SignalKind::terminate())
            .expect("failed to install signal handler")
            .recv()
            .await;
    };

    #[cfg(not(unix))]
    let terminate = std::future::pending::<()>();

    tokio::select! {
        _ = ctrl_c => {
            info!("收到Ctrl+C信号，正在关闭gRPC服务器...");
        }
        _ = terminate => {
            info!("收到终止信号，正在关闭gRPC服务器...");
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{Config, SandboxManager};
    use std::sync::Arc;

    #[tokio::test]
    async fn test_grpc_server_creation() {
        let config = Config::default();
        let sandbox_manager = Arc::new(
            SandboxManager::new(Arc::new(config)).await.unwrap()
        );
        
        let addr = "127.0.0.1:0".parse().unwrap();
        let runner = GrpcServerRunner::new(sandbox_manager, addr);
        
        // 验证创建成功
        assert_eq!(runner.addr.ip().to_string(), "127.0.0.1");
        assert_eq!(runner.addr.port(), 0);
    }
}